package com.sense.kukoo.common.utils;


import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Handler;
import android.text.TextUtils;

import com.sense.kukoo.common.file.FileConfig;
import com.sense.kukoo.lib_logger.LoggerManager;

import java.io.File;
import java.util.Timer;
import java.util.TimerTask;


public class AudioPlayerManager {

    private static final String TAG = AudioPlayerManager.class.getSimpleName();
    private static AudioPlayerManager sInstance = new AudioPlayerManager();
    private static String CURRENT_RECORD_FILE = FileConfig.INSTANCE.getVoiceDir();
    private static int MAGIC_NUMBER = 500;
    private static int MIN_RECORD_DURATION = 1000;
    private Callback mRecordCallback;
    private Callback mPlayCallback;

    private String mAudioRecordPath;
    private MediaPlayer mPlayer;
    private MediaRecorder mRecorder;
    private Handler mHandler;

    private AudioPlayerManager() {
        mHandler = new Handler();
    }

    public static AudioPlayerManager getInstance() {
        return sInstance;
    }


    public void startRecord(Callback callback) {
        mRecordCallback = callback;
        try {
            mAudioRecordPath = CURRENT_RECORD_FILE + "/" + System.currentTimeMillis() + ".m4a";
            mRecorder = new MediaRecorder();
            mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            // 使用mp4容器并且后缀改为.m4a，来兼容小程序的播放
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            mRecorder.setOutputFile(mAudioRecordPath);
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            mRecorder.prepare();
            mRecorder.start();
            // 最大录制时间之后需要停止录制
            mHandler.removeCallbacksAndMessages(null);
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    stopInternalRecord();
                    onRecordCompleted(true, getDuration());
                    mRecordCallback = null;
                }
            }, 30 * 1000);
        } catch (Exception e) {
            LoggerManager.e(TAG, "startRecord failed", e);
            stopInternalRecord();
            onRecordCompleted(false, getDuration());
        }
    }


    public void startRecordWithTimeCallback(Callback callback) {
        mRecordCallback = callback;
        try {
            mAudioRecordPath = CURRENT_RECORD_FILE + "/" + System.currentTimeMillis() + ".m4a";
            mRecorder = new MediaRecorder();
            mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            // 使用mp4容器并且后缀改为.m4a，来兼容小程序的播放
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            mRecorder.setOutputFile(mAudioRecordPath);
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            mRecorder.prepare();
            mRecorder.start();
            // 最大录制时间之后需要停止录制
            startTimer();
        } catch (Exception e) {
            LoggerManager.e(TAG, "startRecord failed", e);
            stopInternalRecord();
            cancelRecordTimer();
            onRecordCompleted(false, 0);
        }
    }


    TimerTask recordTask;
    Timer recordTimer;
    public void startTimer() {
        recordTask= new TimerTask() {
            private volatile int timeCount = 0;
            @Override
            public void run() {
                LoggerManager.e(TAG, "startRecord failed=timeCount="+timeCount);
                if (timeCount >= 15) {//语音抢单最多录音时长15s
                    stopInternalRecord();
                    onRecordCompleted(true, timeCount);
                    mRecordCallback = null;
                    timeCount = 0;
                    this.cancel();
                } else {
                    timeCount++;
                    onRecordCompleted(false, timeCount);
                }
            }
        };

       recordTimer = new Timer();
        recordTimer.schedule(recordTask, 0, 1000);
    }


    public void stopRecord() {
        stopInternalRecord();
        onRecordCompleted(true, getDuration()/1000);
        mRecordCallback = null;
    }

    private void stopInternalRecord() {
        mHandler.removeCallbacksAndMessages(null);
        if (mRecorder == null) {
            return;
        }
        mRecorder.release();
        mRecorder = null;
    }

    public void startPlay(String filePath, Callback callback) {
        mAudioRecordPath = filePath;
        mPlayCallback = callback;
        try {
            mPlayer = new MediaPlayer();
            mPlayer.setDataSource(filePath);
            mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    stopInternalPlay();
                    onPlayCompleted(true);
                    cancelPlayTimer();
                }
            });
            mPlayer.prepare();
            mPlayer.start();
            startPlayTimer();
        } catch (Exception e) {
            //Toast.makeText(ApplicationContext.instance(), ApplicationContext.instance().getText(R.string.common_play_voice_error), Toast.LENGTH_SHORT).show();
            stopInternalPlay();
            onPlayCompleted(false);
        }
    }
    Timer playTimer;
    TimerTask playTask;
    public void startPlayTimer() {

        playTask= new TimerTask() {
            int duration = getDuration();
            int temp = duration / 1000;
            @Override
            public void run() {

                if (temp <= 0) {//播放完
                    if (mPlayCallback != null) {
                        mPlayCallback.onCompletion(true,duration / 1000);
                    }
                    temp = duration;
                    this.cancel();
                } else {
                    temp--;
                    if (mPlayCallback != null) {
                        mPlayCallback.onCompletion(false, temp);
                    }
                }

            }
        };

        playTimer = new Timer();
        playTimer.schedule(playTask, 0, 1000);
    }


    public void stopPlay() {
        stopInternalPlay();
        onPlayCompleted(false);
        mPlayCallback = null;
    }



    public void cancelPlayTimer(){
        if (playTimer!=null){
            playTask.cancel();
            playTimer.cancel();
            playTask=null;
            playTimer=null;
        }
    }
    public void cancelRecordTimer(){
        if (recordTimer!=null){
            recordTimer.cancel();
            recordTask.cancel();
            recordTask=null;
            recordTimer=null;
        }
    }
    private void stopInternalPlay() {
        if (mPlayer == null) {
            return;
        }
        mPlayer.release();
        mPlayer = null;
    }

    public boolean isPlaying() {
        if (mPlayer != null && mPlayer.isPlaying()) {
            return true;
        }
        return false;
    }

    private void onPlayCompleted(boolean success) {
        if (mPlayCallback != null) {
            mPlayCallback.onCompletion(success, getDuration()/1000);
        }
        mPlayer = null;
    }

    private void onRecordCompleted(boolean success, int currentDuration) {
        if (mRecordCallback != null) {
            mRecordCallback.onCompletion(success, currentDuration);
        }
        if (success) {
            mRecorder = null;
            cancelRecordTimer();
        }
    }

    public String getPath() {
        return mAudioRecordPath;
    }

    public int getDuration() {
        if (TextUtils.isEmpty(mAudioRecordPath)) {
            return 0;
        }
        int duration = 0;
        // 通过初始化播放器的方式来获取真实的音频长度
        try {
            MediaPlayer mp = new MediaPlayer();
            mp.setDataSource(mAudioRecordPath);
            mp.prepare();
            duration = mp.getDuration();
            // 语音长度如果是59s多，因为外部会/1000取整，会一直显示59'，所以这里对长度进行处理，达到四舍五入的效果
            if (duration < MIN_RECORD_DURATION) {
                duration = 0;
            } else {
                duration = duration + MAGIC_NUMBER;
            }
        } catch (Exception e) {
            LoggerManager.w(TAG, "getDuration failed", e);
        }
        if (duration < 0) {
            duration = 0;
        }
        return duration;
    }

    public interface Callback {
        void onCompletion(Boolean success, int currentDuration);
    }



    public void deleteVoiceFile(){
        FileUtil.deleteFoder(new File(mAudioRecordPath));
        mAudioRecordPath=null;

    }
}
